package com.study.comtroller;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
public class MyController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/index")
    public String index0() {
        return "index" ;
    }

    //@PathVariable不能为空，不能设置默认值，因为null对于url是无意义的。
    //如果参数确实可能为空，需要默认值，可以使用@RequestParams。
    @RequestMapping("/index/{key}")
    public String index(@PathVariable String key) {
        return "index" + key;
    }

    @RequestMapping("/upload1")
    public Map<String, String> upload1(@RequestParam("file") MultipartFile file)
            throws IOException {
        log.info("[文件类型] - [{}]", file.getContentType());
        log.info("[文件名称] - [{}]", file.getOriginalFilename());
        log.info("[文件大小] - [{}]", file.getSize());
        file.transferTo(new File("D:/logs/" + file.getOriginalFilename()));
        Map<String, String> result = new HashMap<>(16);
        result.put("contentType", file.getContentType());
        result.put("fileSize", file.getSize() + "");
        result.put("fileName", file.getOriginalFilename());
        return result;
    }

    @RequestMapping("/rest")
    public String rest() {

        //getForObject()其实比getForEntity()多包含了将HTTP转成POJO的功能，但是getForObject没有处理response的能力。

        //不带参数请求
        String url = "http://127.0.0.1:8080/index";
        //String url = "https://www.baidu.com/";
        String object = this.restTemplate.getForObject(url, String.class);
        System.out.println("restTemplate getForObject: " + object);

        //带参数的get请求1
        String object1 = this.restTemplate.getForObject(url + "/{1}", String.class, ", test");
        System.out.println("restTemplate getForObject: " + object1);

        // 2-getForEntity()
        ResponseEntity<String> responseEntity1 = this.restTemplate.getForEntity(url, String.class);
        HttpStatus statusCode = responseEntity1.getStatusCode();
        HttpHeaders header = responseEntity1.getHeaders();
        String response2 = responseEntity1.getBody();
        System.out.println("restTemplate getForEntity: " + response2);

        //3. exchange
        //exchange()方法跟上面的getForObject()、getForEntity()、postForObject()、postForEntity()等方法不同之处在于它可以指定请求的HTTP类型。
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        ResponseEntity<String> exchange = this.restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        System.out.println(exchange.getBody());

        return object;
    }

    @RequestMapping("/proxy")
    public String proxy(@RequestBody String url) {

        //getForObject()其实比getForEntity()多包含了将HTTP转成POJO的功能，但是getForObject没有处理response的能力。

        //String url = "https://www.baidu.com/";
        String object = this.restTemplate.getForObject(url, String.class);
        System.out.println("restTemplate getForObject: " + object);

        return object;
    }

    /**
     * 发送文件
     * @return
     * @throws URISyntaxException
     * @throws IOException
     */
    @RequestMapping(value="/sendFile")
    public String sendFile() throws URISyntaxException, IOException {
        MultiValueMap<String, Object> multiPartBody = new LinkedMultiValueMap<>();
        multiPartBody.add("file", new ClassPathResource("tmp/user.txt"));
        RequestEntity<MultiValueMap<String, Object>> requestEntity = RequestEntity
                .post(new URI("http://127.0.0.1:8080/upload1"))
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(multiPartBody);
        ResponseEntity<String> response = restTemplate.exchange(requestEntity, String.class);
        return "sueecess";
    }

    /**
     * 下载文件
     * @param response
     * @throws URISyntaxException
     * @throws IOException
     *
     * //将download.html 下载到本地myframe.html中
     */
    @RequestMapping(value="/receiveFile")
    public void receiveFile(HttpServletResponse response) throws URISyntaxException, IOException {
        // 小文件
        RequestEntity requestEntity = RequestEntity.get(
                new URI("http://127.0.0.1:8080/downLoad.html")).build();
        ResponseEntity<byte[]> responseEntity = restTemplate.exchange(requestEntity, byte[].class);
        byte[] downloadContent = responseEntity.getBody();
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"myframe.html\"");
        response.addHeader("Content-Length", "" + downloadContent.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(downloadContent, response.getOutputStream());
    }

    /**
     * 大文件
     * @param response
     * @return
     * @throws URISyntaxException
     */
    @RequestMapping(value="/bigFile")
    public String bigFile(HttpServletResponse response) throws URISyntaxException {
        //大文件
        ResponseExtractor<ResponseEntity<File>> responseExtractor =
                new ResponseExtractor<ResponseEntity<File>>() {
                    @Override
                    public ResponseEntity<File> extractData(ClientHttpResponse response)
                            throws IOException {
                        File rcvFile = File.createTempFile("rcvFile", "zip");
                        FileCopyUtils.copy(response.getBody(), new FileOutputStream(rcvFile));
                        return ResponseEntity.status(response.getStatusCode()).
                                headers(response.getHeaders()).body(rcvFile);
                    }
                };
        RequestCallback requestCallback = new RequestCallback() {
            @Override
            public void doWithRequest(ClientHttpRequest clientHttpRequest) throws IOException {

            }
        };
        ResponseEntity<File> fileBody = this.restTemplate.execute(
                new URI("http://127.0.0.1:8080/downLoad.html"),
                HttpMethod.GET,  requestCallback, responseExtractor);
        File file = fileBody.getBody();
        file.renameTo(new File("D:/logs/big.html"));
        return "success";
    }
}


/*
设置HTTP Header

// 1-Content-Type
RequestEntity<User> requestEntity = RequestEntity
        .post(new URI(uri))
        .contentType(MediaType.APPLICATION_JSON)
        .body(user);

// 2-Accept
RequestEntity<User> requestEntity = RequestEntity
        .post(new URI(uri))
        .accept(MediaType.APPLICATION_JSON)
        .body(user);

// 3-Other
RequestEntity<User> requestEntity = RequestEntity
        .post(new URI(uri))
        .header("Authorization", "Basic " + base64Credentials)
        .body(user);

 */